#pragma once

#include "ai/AIActor.h"

class Player;

class Object : public AIActor
{
public:
	Object(OBJECT_TYPE objType);
	virtual ~Object();

	virtual void Update(uint64 diffTime) = 0;

	void SetS32Value(size_t index, s32 value);
	void SetF32Value(size_t index, f32 value);

	void ModS32Value(size_t index, s32 value);
	void ModF32Value(size_t index, f32 value);

	s32 GetS32Value(size_t index) const {
		DBGASSERT(index < m_bitMask32.Size());
		return m_s32Values[index];
	}
	f32 GetF32Value(size_t index) const {
		DBGASSERT(index < m_bitMask32.Size());
		return m_f32Values[index];
	}

	void SetS64Value(size_t index, s64 value);
	void SetF64Value(size_t index, f64 value);

	void ModS64Value(size_t index, s64 value);
	void ModF64Value(size_t index, f64 value);

	s64 GetS64Value(size_t index) const {
		DBGASSERT(index < m_bitMask64.Size());
		return m_s64Values[index];
	}
	f64 GetF64Value(size_t index) const {
		DBGASSERT(index < m_bitMask64.Size());
		return m_f64Values[index];
	}

	void SetFlag(size_t index, uint32 flag);
	void RemoveFlag(size_t index, uint32 flag);

	bool HasFlag(size_t index, uint32 flag) const;
	bool HasOneOfFlag(size_t index, uint32 flags) const;

	void SetGuid(ObjGUID guid) { m_guid = guid; }
	ObjGUID GetGuid() const { return m_guid; }
	uint32 GetGuidLow() const { return m_guid.UID; }

	OBJECT_TYPE GetObjectType() const { return m_objType; }
	bool IsType(OBJECT_TYPE objType) const { return IS_TYPE(m_objType, objType); }
	bool IsKindOf(OBJECT_TYPE objType) const { return IS_KIND_OF(m_objType, objType); }

	void SetDirty32(size_t index) { m_bitMask32.SetDirty(index); }
	void SetDirty64(size_t index) { m_bitMask64.SetDirty(index); }
	void ResetDirty32() { m_bitMask32.Reset(); }
	void ResetDirty64() { m_bitMask64.Reset(); }
	bool IsDirty32() const { return m_bitMask32.IsDirty(); }
	bool IsDirty64() const { return m_bitMask64.IsDirty(); }

	virtual void BuildCreatePacketForPlayer(INetPacket& pck, Player* pPlayer);

	virtual const std::string& GetName() const { return emptyString; }

protected:
	void BuildValue32UpdatePacket(INetPacket& pck) const;
	void BuildValue64UpdatePacket(INetPacket& pck) const;

	const OBJECT_TYPE m_objType;
	ObjGUID m_guid;

	union {
		s32* m_s32Values;
		f32* m_f32Values;
	};
	CBitMask m_bitMask32;

	union {
		s64* m_s64Values;
		f64* m_f64Values;
	};
	CBitMask m_bitMask64;
};
